package com.demo.mvc.ioc;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.lang.annotation.Annotation;
import java.util.Map;


/**
 * @author luogq
 */
@Slf4j
public class People006 implements BeanNameAware, BeanFactoryAware, ApplicationContextAware,
    BeanPostProcessor, DisposableBean, InitializingBean {

  Animal animal;
  String beanName;
  BeanFactory beanFactory;
  ApplicationContext applicationContext;

  public ApplicationContext getApplicationContext(){
    return this.applicationContext;
  }

  @PostConstruct
  public void People006(  ){
    log.info("PostConstruct 注解执行");
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    log.info("InitializingBean afterPropertiesSet run ");
  }

  @Override
  public void destroy() throws Exception {
    log.info("DisposableBean destroy 执行");
  }

  @PreDestroy
  public void preDestory(  ){
    log.info("PreDestroy 注解执行");
  }


  public void setAnimal(){
    Map<String, Animal> objectObjectHashMap = applicationContext.getBeansOfType(Animal.class);
    for(Map.Entry<String, Animal> animal : objectObjectHashMap.entrySet()){
      log.info("setAnimal,{}", animal.getClass());
      if (CatImpl.class.getName().equals(animal.getValue().getClass().getName())){
        this.animal= animal.getValue();
        break;
      }
    }
  }


  public void myAnimalSay(){
    animal.say();
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    log.info("ApplicationContextAware setApplicationContext run ");
    this.applicationContext = applicationContext;
  }

  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    log.info("BeanFactoryAware setBeanFactory run ");
    this.beanFactory = beanFactory;
  }

  @Override
  public void setBeanName(String s) {
    log.info("BeanNameAware setBeanName run ");
    this.beanName = s;
  }

  @Override
  @Nullable
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (People006.class.getName().equals(bean.getClass().getName())) {
      log.info("BeanPostProcessor postProcessBeforeInitialization run ");
    }
    return bean;
  }

  @Override
  @Nullable
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (People006.class.getName().equals(bean.getClass().getName())) {
      log.info("BeanPostProcessor postProcessAfterInitialization run ");
    }
    return bean;
  }

  private void initP006() {
    log.info("People006 initMethod run ");
  }
}
